#include "../config.h"

#include <sys/utsname.h>
#include <sstream>
#include <gtkmm.h>
#include <boost/algorithm/string.hpp>

#include "environment.h"

namespace gpyp {
namespace env {

namespace {
bool load_file(const std::string &path, std::string &content) {
  bool   res    = false;
  gchar *data   = NULL;
  gsize  length = 0;
  if (g_file_get_contents(path.c_str(), &data, &length, NULL)) {
    for(gsize i = 0; i < length; ++i) {
      if (!data[i]) data[i] = ' ';
    }
    content.assign(data, length);
    res = true;
  }
  if (data) g_free(data);
  return res;
}
}

/*
struct utsname {
  char sysname[];  // Linux
  char nodename[]; //
  char release[];  // 2.6.27-7-generic
  char version[];  // #1 SMP Fri Oct 17 22:24:21 UTC 2008
  char machine[];  // i686
#ifdef _GNU_SOURCE
  char domainname[];
#endif
};
*/
Glib::ustring get_os() {
  std::stringstream ss;
  struct utsname *u = (struct utsname *)g_malloc(sizeof(struct utsname));
  if (uname(u) == 0) {
    ss << u->sysname << " " << u->release << " " << u->machine;
  }
  g_free(u);
  return ss.str();
}
Glib::ustring get_distribution() {
  /* JDのソースの移植 */

  std::string res;
  std::string text_content;

  if (load_file("/etc/lsb-release", text_content)) {
    std::vector<std::string> lines;
    boost::algorithm::split(lines, text_content, boost::is_any_of("\n"));

    for(std::vector<std::string>::reverse_iterator iter = lines.rbegin();
        iter != lines.rend(); ++iter) {
      std::string::size_type p = std::string::npos;
      if ((p = iter->find("=")) == std::string::npos) continue;

      std::string key(*iter, 0, p), val(*iter, p + 1);
      boost::trim(key);
      boost::trim(val);
      boost::trim_if(val, std::bind2nd(std::equal_to<char>(), '\"'));

      if (key == "DISTRIB_DESCRIPTION" && !val.empty()) {
        res = val;
        break;
      }
    }
  } else if (load_file("/etc/knoppix-version", text_content)) {
    res = std::string("KNOPPIX ") + text_content;
  } else if (load_file("/etc/debian_version", text_content)) {
    res = std::string("Debian GNU/Linux ") + text_content;
  } else if (load_file("/etc/arch-release", text_content)) {
    res = "Arch Linux";
  } else if (load_file("/etc/release", text_content)) {
    std::vector<std::string> lines;
    boost::algorithm::split(lines, text_content, boost::is_any_of("\n"));

    for(std::vector<std::string>::reverse_iterator iter = lines.rbegin();
        iter != lines.rend(); ++iter) {
      if (iter->find("BeleniX")  != std::string::npos ||
          iter->find("Nexenta")  != std::string::npos ||
          iter->find("SchilliX") != std::string::npos ||
          iter->find("Solaris")  != std::string::npos) {
        res = *iter;
        break;
      }
    }
  } else {
    const char *dist_files[] = {
      "/etc/fedora-release",
      "/etc/gentoo-release",
      "/etc/lfs-release",
      "/etc/mandriva-release",
      "/etc/momonga-release",
      "/usr/lib/setup/plamo-version",
      "/etc/puppyversion",
      "/etc/redhat-release", // Redhat, CentOS, WhiteBox, PCLinuxOS
      "/etc/sabayon-release",
      "/etc/slackware-version",
      "/etc/SuSE-release",
      "/etc/turbolinux-release",
      "/etc/vine-release",
      "/etc/zenwalk-version",
      NULL
    };
    for(const char **path = dist_files; *path; ++path) {
      if (load_file(*path, text_content)) {
        res = text_content;
        break;
      }
    }
  }

  for(std::string::iterator iter = res.begin();
      iter != res.end(); ++iter) {
    if (*iter < 0x20 || *iter > 0x7E) {
      res.erase(iter, res.end());
      break;
    }
  }

  boost::trim(res);

  return res;
}
Glib::ustring get_de() {
  bool found = false;
  std::string wm = Glib::getenv("DESKTOP_SESSION", found);
  if      (wm.find("gnome") != std::string::npos) return "GNOME";
  else if (wm.find("kde")   != std::string::npos) return "KDE";
  else if (wm.find("xfce")  != std::string::npos) return "Xfce";
  else {
    bool found = false;
    Glib::getenv("GNOME_DESKTOP_SESSION_ID", found);
    if (found) return "GNOME";

    Glib::getenv("KDE_FULL_SESSION", found);
    if (found) return "KDE";
  }
  return wm;
}
Glib::ustring get_gtkmm_version() {
  std::stringstream ss;
  ss << GTKMM_MAJOR_VERSION << "."
     << GTKMM_MINOR_VERSION << "."
     << GTKMM_MICRO_VERSION;
  return ss.str();
}
Glib::ustring get_glibmm_version() {
  std::stringstream ss;
  ss << GLIBMM_MAJOR_VERSION << "."
     << GLIBMM_MINOR_VERSION << "."
     << GLIBMM_MICRO_VERSION;
  return ss.str();
}

}/* namespace env */
}/* namespace gpyp */
